#include "point.h"
#include <math.h>

using namespace m3d;

SPoint2F::SPoint2F( ){ };

SPoint2F::SPoint2F( float _x, float _y )
:x(_x),y(_y)
{};

SPoint2F SPoint2F::operator + ( const SPoint2F& b ) const
{
	return SPoint2F(x+b.x, y+b.y);
}

SPoint2F SPoint2F::operator - ( const SPoint2F& b ) const
{
	return SPoint2F(x-b.x, y-b.y);
}

SPoint2F SPoint2F::operator * ( float _scalar ) const
{
	return SPoint2F(x*_scalar, y*_scalar);
}

SPoint2F SPoint2F::operator / ( float _scalar ) const
{
	return SPoint2F(x/_scalar, y/_scalar);
}

SPoint2F& SPoint2F::operator += ( const SPoint2F& b )
{
	x += b.x; 
	y += b.y;
	return *this;
}

SPoint2F& SPoint2F::operator -= ( const SPoint2F& b )
{
	x -= b.x; 
	y -= b.y;
	return *this;
}

SPoint2F& SPoint2F::operator *= ( float _scalar )
{
	x *= _scalar;
	y *= _scalar;
	return *this;
}

SPoint2F& SPoint2F::operator /= ( float _scalar )
{
	x /= _scalar;
	y /= _scalar;
	return *this;
}

SPoint2F& SPoint2F::operator = ( const SPoint2F& b )
{
	x = b.x; 
	y = b.y;
	return *this;
}

bool SPoint2F::operator == ( const SPoint2F& b ) const
{ 
	return b.x == x && b.y == y; 
};

bool SPoint2F::operator != ( const SPoint2F& b ) const
{ 
	return b.x != x || b.y != y; 
};

float SPoint2F::Length( void ) const
{ 
	double l = x*x+y*y;
	if( l )
		l = sqrt(l);
	return (float)l;
};

double SPoint2F::SqLength( void ) const
{ 
	return x*(double)x+y*(double)y;
};

float SPoint2F::Dot( const SPoint2F& _v ) const
{
	return x*_v.x + y*_v.y;
};

SPoint2F& SPoint2F::Normalize( void )
{
	double l = SqLength();
	if( l )
	{
		l = sqrt(l);
		x /= (float)l;
		y /= (float)l;
	}
	return *this;
};

float SPoint2F::AngleWith( const SPoint2F& v ) const
{
   return (float)acos( ((*this).Dot(v)) / (this->Length()*v.Length()) );
}